package com.example.springboot.globalutils;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageInfo;

import java.util.List;
import java.util.Objects;

public class R<T> {
    private final Integer code;
    private final String msg;
    private T data;

    private R() {
        this.code = 0;
        this.msg = "请求成功";
    }

    private R(Integer code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    private R(Integer code, T data) {
        this.code = code;
        this.msg = "请求成功";
        this.data = data;
    }

    private R(Integer code, String msg, T data) {
        this.code = code;
        this.msg = msg;
        this.data = data;
    }

    private R(T data) {
        this();
        this.data = data;
    }

    public static <T> R<T> fail() {
        return new R(500, "未知异常，请联系管理员");
    }

    public static <T> R<T> fail(BizException e) {
        return new R(e.getCode(), e.getMsg());
    }

    public static <T> R<T> fail(String msg) {
        return new R(500, msg);
    }

    public static <T> R<T> fail(Integer code, String msg) {
        return new R(code, msg);
    }

    public static <T> R<T> success(T data) {
        return new R(data);
    }

    public static <T> R<T> success(Integer code, T data) {
        return new R(code, data);
    }

    public static <T> R<T> success(Integer code, String msg, T data) {
        return new R(code, msg, data);
    }

    public static <T> R<Paged<T>> success(IPage<T> paged) {
        return withPage(paged);
    }

    public static <T> R<Paged<T>> success(Page<T> paged) {
        return withPage(paged);
    }

    public static <T> R<Paged<T>> success(PageInfo<T> paged) {
        return withPage(paged);
    }

    public static R<Void> success() {
        return new R();
    }

    public static <T> R<Paged<T>> withPage(Paged<T> paged) {
        return new R(paged);
    }

    public static <T> R<Paged<T>> withPage(IPage<T> paged) {
        Paged<T> wrap = Paged.wrap(paged);
        return new R(wrap);
    }

    public static <T> R<Paged<T>> withPage(Page<T> paged) {
        Paged<T> wrap = Paged.wrap(paged);
        return new R(wrap);
    }

    public static <T> R<Paged<T>> withPage(PageInfo<T> paged) {
        Paged<T> wrap = Paged.wrap(paged);
        return new R(wrap);
    }

    public static <T> R<Paged<T>> withPage(long pageNum, long pageSize, long total, List<T> list) {
        Paged<T> wrap = Paged.wrap(pageNum, pageSize, total, list);
        return new R(wrap);
    }

    public Integer getCode() {
        return this.code;
    }

    public String getMsg() {
        return this.msg;
    }

    public T getData() {
        return this.data;
    }

    public Boolean isSuccess() {
        return Objects.equals(0, this.code);
    }

    @JsonIgnore
    public T ok() {
        if (Objects.equals(this.code, ReturnCodeEnums.SUCCESS.getCode())) {
            return this.data;
        } else {
            throw new BizException(this.code, this.msg);
        }
    }
}
